import wx
import wx.lib.evtmgr as em

from events import *

class Language:
    
    def __init__(self):
        self.__strings_fr = {
           "menu.file.open" : "Ouvrir ...",
           "menu.file.close" : "Fermer",
           "label.filename": "Nom du fichier",
           "label.new.filename" : "Nouveau nom du fichier",
           "chk.extension.lower.case" : "Extention en minuscules",
           "chk.numerotation" : "Numerotation",
           "btn.rename" : "Renommer",
           "status.bar.open.title" : "Ouvrir un dossier",
           "status.bar.close.title" : "Fermer le media courant",
           "directory.chooser.open.dir.title" : "Choisissez un dossier",
           "application.quit.confirmation.message" : "Voulez-vous vraiment quitter ?"
           }

ID_NEW_FILENAME_TEXT = 300
ID_BTN_RENAME = 301

class ImagePanel(wx.Panel):
    def __init__(self, parent, controller):
        wx.Panel.__init__(self, parent)
        self.__controller = controller
        controller.AddViewer(self)
        sizer = wx.GridBagSizer(9,9)
        self.__imagePanel = wx.Panel(self, -1, style=wx.SUNKEN_BORDER)
        self.__imagePanel.SetBackgroundColour(wx.LIGHT_GREY)
        
        self.__imagePanel.image = None
        
        self.__oldFilenameLabel = wx.StaticText(self, -1, "Filename: ")
        self.__oldFilenameLabelValue = wx.StaticText(self, -1)
        self.__newFilenameLabel = wx.StaticText(self, -1, "New filename: ")
        self.__newFilenameText = wx.TextCtrl(self, ID_NEW_FILENAME_TEXT, style = wx.TE_PROCESS_ENTER)
        self.__renameButton = wx.Button(self, ID_BTN_RENAME, "Rename")
        self.__renameButton.Enable(len(self.__newFilenameText.GetValue().strip()) > 0)
        self.__newFilenameText.Enable(False)
        self.__lowerExtensionChk = wx.CheckBox(self, -1, "Extension in lowercase")
        self.__lowerExtensionChk.SetValue(wx.CHK_CHECKED)
        self.__numerotationChk = wx.CheckBox(self, -1, "Numerotation")
        self.__numerotationChk.SetValue(wx.CHK_CHECKED)

        self.__img = None
        self.__bitmap = None
        
        sizer.Add(self.__oldFilenameLabel, (0,0), wx.DefaultSpan)
        sizer.Add(self.__oldFilenameLabelValue, (0,1), wx.DefaultSpan)
        sizer.Add(self.__lowerExtensionChk, (1,0))
        sizer.Add(self.__numerotationChk, (1,1))
        sizer.Add(self.__newFilenameLabel, (2,0), (1, 1))
        sizer.Add(self.__newFilenameText, (2,1), (1, 1), wx.EXPAND)
        sizer.Add(self.__renameButton, (2,2))
        
        sizer.Add(self.__imagePanel, (3,0), (1, 3), wx.EXPAND)
        
        sizer.AddGrowableCol(1)
        sizer.AddGrowableRow(3)
        
        self.SetSizerAndFit(sizer)
        
        wx.EVT_SIZE(self.__imagePanel, self.OnSize)
        
        self.Bind(wx.EVT_TEXT, self.__OnText, id = ID_NEW_FILENAME_TEXT)
        self.Bind(wx.EVT_TEXT_ENTER, self.__OnTextEnter, id = ID_NEW_FILENAME_TEXT)
        self.Bind(wx.EVT_BUTTON, self.__OnBtnRenameClick, id = ID_BTN_RENAME)
        
        self.Bind(EVT_FILE_SELECTED, self.__OnFileSelected)
        self.Bind(EVT_FILE_UNSELECTED, self.__OnFileUnSelected)
        self.Bind(EVT_FILE_RENAMED, self.__OnFileRenamed)
    
    def __OnFileRenamed(self, event):
        self.__oldFilenameLabelValue.SetLabel(event.GetValue().GetFilename())
    
    def __OnBtnRenameClick(self, event):
        self.__SendRename()
    
    def __OnFileUnSelected(self, event):
        self.__newFilenameText.Enable(event.IsSelected())
        self.__renameButton.Enable(event.IsSelected() and len(self.__newFilenameText.GetValue().strip()) > 0)
    
    def __OnFileSelected(self, event):
        self.__newFilenameText.Enable(event.IsSelected())
        fileItem = event.GetValue()
        self.Draw(fileItem.GetPath())
        self.__oldFilenameLabelValue.SetLabel(fileItem.GetFilename())
        self.__renameButton.Enable(event.IsSelected() and len(self.__newFilenameText.GetValue().strip()) > 0)
    
    def __OnText(self, evt):
        self.__renameButton.Enable(len(self.__newFilenameText.GetValue().strip()) > 0)
    
    def __OnTextEnter(self, event):
        if len(self.__newFilenameText.GetValue().strip()) > 0:
            self.__SendRename()
            self.__newFilenameText.SelectAll()
    
    def GetImgSize(self):
        if self.__img != None:
            return (self.__img.GetWidth(), self.__img.GetHeight())
        else:
            return None
    
    def OnSize(self, evt):
        w, h = evt.GetSize()
        self.Rescale(w, h)
        evt.Skip()

    def Draw(self, path):
        self.Erase()
        self.__img = wx.Image(path, wx.BITMAP_TYPE_ANY)
        w, h = self.__imagePanel.GetSize()
        self.Rescale(w, h)
        self.Refresh()
    
    def Rescale(self, w, h):
        if self.__img != None:
            img = self.__img.Copy()
            r = min(float(w)/float(img.GetWidth()),float(h)/float(img.GetHeight()))
            if r > 1:
                r = 1
            self.Erase()
            img.Rescale(img.GetWidth()*r, img.GetHeight()*r)
            self.__bitmap = wx.StaticBitmap(self.__imagePanel, -1, img.ConvertToBitmap())
    
    def Erase(self):
        if self.__bitmap != None:
            self.__bitmap.Destroy()
            self.__bitmap = None
    
    def __SendRename(self):
        evt = EventRename(myEVT_RENAME, self.__lowerExtensionChk.IsChecked(), self.__numerotationChk.IsChecked())
        evt.SetValue(self.__newFilenameText.GetValue())
        self.GetEventHandler().ProcessEvent(evt)


ID_LISTBOX = 200
ID_COMBOBOX = 201
ID_BTN_NEXT = 202
ID_BTN_PREVIOUS = 203

class FileDrop(wx.FileDropTarget):
    def __init__(self, window, controller):
        wx.FileDropTarget.__init__(self)
        self.window = window
        self.__controller = controller

    def OnDropFiles(self, x, y, filenames):
        if len(filenames) == 1:
            self.__controller.SetMediaDir(filenames[0])
            

class FileListBoxPanel(wx.Panel):
    def __init__(self, parent, controller, style=wx.RAISED_BORDER):
        wx.Panel.__init__(self, parent, style = style)
        self.__controller = controller
        controller.AddViewer(self)
        self.__items = []
        self.__btnNext = wx.Button(self, ID_BTN_NEXT, ">", size = (50, -1))
        self.__btnPrevious = wx.Button(self, ID_BTN_PREVIOUS, "<", size = (50, -1)) 
        sizer = wx.BoxSizer(wx.VERTICAL)
        buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
        buttonSizer.Add(self.__btnPrevious)
        buttonSizer.Add(self.__btnNext)
        
        self.__mediaType = wx.ComboBox(self, ID_COMBOBOX, choices = ['jpg', 'png', 'gif'], style=wx.CB_DROPDOWN)
        self.__mediaType.SetSelection(0)
        self.__fileList = wx.ListBox(self, ID_LISTBOX, size = (-1, -1), style = wx.LB_SORT)
        
        dt = FileDrop(self.__fileList, controller)
        self.__fileList.SetDropTarget(dt)
        
        sizer.Add(self.__mediaType)
        sizer.Add(self.__fileList, 1, wx.EXPAND)
        sizer.Add(buttonSizer, border = 2, flag = wx.EXPAND)
        
        self.SetSizer(sizer)
        self.Bind(wx.EVT_LISTBOX, self.OnSelect, id=ID_LISTBOX)
        self.Bind(wx.EVT_COMBOBOX, self.OnCboChange, id=ID_COMBOBOX)
        self.Bind(wx.EVT_TEXT_ENTER, self.OnCboChange, id=ID_COMBOBOX)
        self.Bind(wx.EVT_BUTTON, self.OnBtnNextClick, id=ID_BTN_NEXT)
        self.Bind(wx.EVT_BUTTON, self.OnBtnPreviousClick, id=ID_BTN_PREVIOUS)
        
        self.Bind(EVT_FILES_LOADED, self.__SetContentList)
        self.Bind(EVT_FILE_RENAMED, self.__OnFileRenamed)            
    
    def __OnFileRenamed(self, event):
        fileItem = event.GetValue()
        index = self.__fileList.GetSelection()
        self.__MoveSelection(1)
        self.__fileList.SetString(index, fileItem.GetFilename())
        for item in self.__items:
            if item.GetId() == fileItem.GetId():
                item.UpdateByPath(fileItem.GetPath())
                
        
    
    def OnBtnPreviousClick(self, event):
        self.__MoveSelection(-1)

    def OnBtnNextClick(self, event):
        self.__MoveSelection(1)
    
    def __MoveSelection(self, direction):
        index = self.__fileList.GetSelection()
        
        if not self.__fileList.IsEmpty():
            if index == -1 and direction == 1:
                self.__fileList.Select(0)
                self.__SendListEvent()
            if index != -1:
                if (direction == 1 and index < self.__fileList.GetCount()-1) or (direction == -1 and index > 0):
                    self.__fileList.Select(index + direction)
                    self.__SendListEvent()
    
    def UnSelect(self):
        self.__fileList.Select(-1)
        
        index = self.__fileList.GetSelection()
        evt = EventListBox(myEVT_FILE_UNSELECTED, index != -1)
        evt.SetValue(None)
        self.GetEventHandler().ProcessEvent(evt)
        

    def __SetContentList(self, event):
        items = event.GetValue()
        self.__items = items
        self.__items.sort()
        self.FilterList()
        if not self.__fileList.IsEmpty():
            self.__fileList.Select(0)
            self.__SendListEvent()
    
    def GetSelectedName(self):
        index = self.__fileList.GetSelection()
        if self.__fileList != None and index != wx.NOT_FOUND:
            return self.__fileList.GetString(index)
        else:
            return ""
    def GetSelectedItem(self):
        index = self.__fileList.GetSelection()
        if self.__fileList != None and index != wx.NOT_FOUND:
            return self.__fileList.GetClientData(index)
        else:
            return None
    def GetSelectedIndex(self):
        return self.__fileList.GetSelection()
    
    def GetItemCount(self):
        return self.__fileList.GetCount()
    
    def OnSelect(self, event):
        self.__SendListEvent()
        event.Skip()
        
    def OnCboChange(self, event):
        self.FilterList()
    
    def FilterList(self):
        self.__fileList.Clear()
        value = self.__mediaType.GetValue()
        for item in self.__items:
            if value == "" or item.__str__().lower().find(value.lower()) != -1:
                self.__fileList.Append(item.__str__(), item)
    
    def __SendListEvent(self):
        index = self.__fileList.GetSelection()
        evt = EventListBox(myEVT_FILE_SELECTED, index != -1)
        evt.SetValue(self.__fileList.GetClientData(index))
        self.GetEventHandler().ProcessEvent(evt)
        




ID_CLOSE = 100
ID_OPEN = 101
class MainFrame(wx.Frame):
    
    def __init__(self, parent, controller):
        wx.Frame.__init__(self, parent, wx.ID_ANY, "MediaSmool", wx.DefaultPosition, (700, 470))
        self.__listPanel = None
        self.__imagePanel = None
        self.__menuBar = None
        self.__controller = controller
        
        self.__splitter = wx.SplitterWindow(self, -1)
        self.__splitter.SplitVertically(self.__getListPanel(), self.__getImagePanel(), 250)
        wx.EVT_SIZE(self, self.OnSize)
        wx.EVT_CLOSE(self, self.__handleExit)
                
        self.SetMenuBar(self.__getMenuBar())
        self.CenterOnScreen()
        self.__statusBar = self.CreateStatusBar()
        self.Show(True)
        self.__getImagePanel().SetFocus()
        
        self.Bind(EVT_FILE_SELECTED, self.__SendEventToImagePanel)
        self.Bind(EVT_FILE_UNSELECTED, self.__SendEventToImagePanel)
        self.Bind(EVT_FILES_LOADED, self.__SendEventToListPanel)
        self.Bind(EVT_RENAME, self.__OnRename)
        self.Bind(EVT_FILE_RENAMED, self.__OnFileRenamed)
    
    def __OnFileRenamed(self, event):
        pass
        
    
    def __OnRename(self, event):
        newName = event.GetValue()
        if event.WithNumerotation():
            count = self.__listPanel.GetItemCount()
            if count < 100: count = 100
            prefix = self.__FormatNumber(self.__listPanel.GetSelectedIndex() + 1, count)
        else:
            prefix = ""
        fileItem = self.__listPanel.GetSelectedItem()
        try:
            self.__controller.Rename(newName, fileItem, event.RenameInLowercase(), prefix)
        except Exception, e:
            dlg = wx.MessageDialog(self, e.message,'MediaSmool',wx.ICON_ERROR)
            dlg.ShowModal()
    
    def __SendEventToListPanel(self, event):
        self.__listPanel.AddPendingEvent(event)
    
    def __SendEventToImagePanel(self, event):
        self.__imagePanel.AddPendingEvent(event)
        
    def GetController(self):
        return self.__controller
        
    def OnSize(self, evt):
        self.__setTitle()
        evt.Skip()

    def __FormatNumber(self, num, count):
        s = ""
        if count < 10:
            return s + "%s" % num
        else:
            numLen = len("%s" % num)
            countLen = len("%s" % count)
            if numLen >= countLen:
                s += self.__FormatNumber(num, count/10)
            else:
                s += "0" + self.__FormatNumber(num, count/10)
        return s

    def __setTitle(self):
        filename = self.__getListPanel().GetSelectedName()
        size = self.__getImagePanel().GetImgSize()
        if size != None:
            w, h = size
            self.__statusBar.SetStatusText("%s [%dx%d]" % (filename, w, h))
        else:
            self.__statusBar.SetStatusText("")

    def setFileNames(self, fileNames):
        self.__listPanel.SetContentList(fileNames)
    
    def setImgByPath(self, path):
        self.__imagePanel.Draw(path)
        self.__setTitle()
    
    def __getMenuBar(self):
        if self.__menuBar == None:
            self.__menuBar = wx.MenuBar()
            menu1 = wx.Menu()
            menu1.Append(ID_OPEN, "&Open\tCTRL+o", "Open a directory image")
            menu1.Append(ID_CLOSE, "&Close\tCTRL+w", "Close current opened media")
            
            self.__menuBar.Append(menu1, "&File")
            self.Bind(wx.EVT_MENU, self.__handleOpen, id=ID_OPEN)
            self.Bind(wx.EVT_MENU, self.__handleClose, id=ID_CLOSE)
        return self.__menuBar

    def __getListPanel(self):
        if self.__listPanel == None:
            self.__listPanel = FileListBoxPanel(self.__splitter, self.__controller)
        return self.__listPanel

    def __getImagePanel(self):
        if self.__imagePanel == None:
            self.__imagePanel = ImagePanel(self.__splitter, self.__controller)
        return self.__imagePanel

    def __handleClose(self, event):
        self.__getImagePanel().Erase()
        self.__getListPanel().UnSelect()
    
    def __handleExit(self, event):
        dlg = wx.MessageDialog(self, 'Do you really want to close this program ?','MediaSmool',wx.YES_NO | wx.ICON_INFORMATION)
        if dlg.ShowModal() == wx.ID_YES:
            event.Skip()
        dlg.Destroy()
        
    def __handleOpen(self, event):
        dlg = wx.DirDialog(self, "Choose a directory:",style=wx.DD_DEFAULT_STYLE, defaultPath = self.__controller.GetMediaDir())
        if dlg.ShowModal() == wx.ID_OK:
            self.__dir = dlg.GetPath()
            self.__controller.SetMediaDir(dlg.GetPath())
        dlg.Destroy()

    def getDir(self):
        return self.__dir
